#include "GameEngine.h"
#include <time.h>
#include <stdlib.h>

GameEngine::TileItem GameEngine::Tiles[16];
time_t GameEngine::StartTime = 0;
int GameEngine::ElapsedSeconds = 0;
int GameEngine::MoveCount = 0;

void GameEngine::Init()
{
	GameEngine::Tiles[0].X = 3;
	GameEngine::Tiles[0].Y = 3;

	for(int index = 1; index<16; index++)
	{
		GameEngine::Tiles[index].X = (index - 1) % 4;
		GameEngine::Tiles[index].Y = (index - 1) / 4;

		char buffer[255];
		TIXML_SNPRINTF(buffer, 255, "tile%d", index);
		GameEngine::Tiles[index].JQuadName = buffer;
	}
}

void GameEngine::MoveLeftTile()
{
	StartTimer();

	GameEngine::TileItem& zeroTile = GameEngine::Tiles[0];

	if(zeroTile.X > 0)
	{
		for(int index = 1; index<16; index++)
		{
			GameEngine::TileItem& currentTile = GameEngine::Tiles[index];

			if(currentTile.Y == zeroTile.Y && currentTile.X == (zeroTile.X-1))
			{
				currentTile.X++;
				currentTile.XMoveStep = TILE_SMOOTH_MOVE_STEPS;
				zeroTile.X--;

				MoveCount++;

				break;
			}
		}
	}
}

void GameEngine::MoveRightTile()
{
	StartTimer();


	GameEngine::TileItem& zeroTile = GameEngine::Tiles[0];

	if(zeroTile.X < 3)
	{
		for(int index = 1; index<16; index++)
		{
			GameEngine::TileItem& currentTile = GameEngine::Tiles[index];

			if(currentTile.Y == zeroTile.Y && currentTile.X == (zeroTile.X+1))
			{
				currentTile.X--;
				currentTile.XMoveStep = -1*TILE_SMOOTH_MOVE_STEPS;
				zeroTile.X++;

				MoveCount++;

				break;
			}
		}
	}
}

void GameEngine::MoveUpTile()
{
	StartTimer();

	GameEngine::TileItem& zeroTile = GameEngine::Tiles[0];

	if(zeroTile.Y > 0)
	{
		for(int index = 1; index<16; index++)
		{
			GameEngine::TileItem& currentTile = GameEngine::Tiles[index];

			if(currentTile.X == zeroTile.X && currentTile.Y == (zeroTile.Y-1))
			{
				currentTile.Y++;
				currentTile.YMoveStep = TILE_SMOOTH_MOVE_STEPS;
				zeroTile.Y--;

				MoveCount++;

				break;
			}
		}
	}
}

void GameEngine::MoveDownTile()
{
	StartTimer();

	GameEngine::TileItem& zeroTile = GameEngine::Tiles[0];

	if(zeroTile.Y < 3)
	{
		for(int index = 1; index<16; index++)
		{
			GameEngine::TileItem& currentTile = GameEngine::Tiles[index];

			if(currentTile.X == zeroTile.X && currentTile.Y == (zeroTile.Y+1))
			{
				currentTile.Y--;
				currentTile.YMoveStep = -1*TILE_SMOOTH_MOVE_STEPS;
				zeroTile.Y++;

				MoveCount++;

				break;
			}
		}
	}
}

void GameEngine::NewGame()
{
	Init();
	Shuffle();

	ResetTimer();
}

void GameEngine::ResetTimer()
{
	ElapsedSeconds = 0;	
	StartTime = 0;
	MoveCount = 0;
}

void GameEngine::StartTimer()
{
	if(StartTime==0)
		StartTime = time(NULL);	
}

int GameEngine::GetElapsedSeconds()
{
	if(StartTime==0)
		return ElapsedSeconds;

	return ElapsedSeconds + time(NULL) - StartTime;
}


void GameEngine::Shuffle()
{
	srand((unsigned)time(NULL));

	for(int index=0;index<212; index++)
	{
		int randId = rand();

		switch(randId % 4)
		{
		case 0:
			MoveDownTile();
			break;
		case 1:
			MoveLeftTile();
			break;
		case 2:
			MoveUpTile();
			break;
		case 3:
			MoveRightTile();
			break;
		}
	}
}

bool GameEngine::IsUserWin()
{
	for(int index = 1; index<16; index++)
	{
		GameEngine::TileItem& currentTile = GameEngine::Tiles[index];

		if(currentTile.X != (index - 1)%4 || currentTile.Y != (index-1)/4)
		{
			return false;
		}
	}

	ElapsedSeconds = GetElapsedSeconds();
	StartTime = 0;

	return true;
}

void GameEngine::Resume()
{
	StartTimer();
}

void GameEngine::Pause()
{
	ElapsedSeconds = GetElapsedSeconds();
	StartTime = 0;
}

int GameEngine::GetMoveCount()
{
	return MoveCount;
}